require 'csputil'
require 'socket'
class Object
  def enum(*list)
    mc = Module === self ? self : self.class
    list.flatten.each_with_index{|e, i| mc.const_set e.to_s.intern, i}
  end
  def bit_enum(*list)
    mc = Module === self ? self : self.class
    list.flatten.each_with_index{|e, i| mc.const_set e.to_s.intern,  2 ** i}
  end
end
class JSlingCommon
  class ProxyType 
    enum %w(PROXY_JSTUNT PROXY_DOMAIN PROXY_FIXED)
  end
  @@proxyFixedAddress = nil
  @@proxyType=ProxyType::PROXY_DOMAIN
  @@proxyPort =443 #51641
  def JSlingCommon.proxyPort
    @@proxyPort
  end
  def JSlingCommon.init(pr="DOMAIN",host=nil, port=51641)
    @@proxyPort = port if port!=nil
    case pr
    when "JSTUNT"
      @@proxyType=ProxyType::PROXY_JSTUNT
    when "FIXED"
      if host!=nil
        @@proxyFixedAddress=["AF_INET",@@proxyPort,nil,JSlingCommon.host2ip(host)]
        @@proxyType=ProxyType::PROXY_FIXED
      end
    else#when "DOMAIN" #default solution
      @@proxyType=ProxyType::PROXY_DOMAIN
    end
  end
  def JSlingCommon.resolveProxy(uri)
    res=nil
    case @@proxyType
    when ProxyType::PROXY_JSTUNT
      res=JSlingCommon.resolveProxyJSTUNT(uri)
    when ProxyType::PROXY_DOMAIN
      res=JSlingCommon.resolveProxyDomain(uri)
    when ProxyType::PROXY_FIXED
      res=JSlingCommon.resolveProxyFixed(uri)
    end
    res[3]==nil ? nil: Util.socketAddress(res)[0]
  end  
  def JSlingCommon.dnsScrub uri
    "X"+uri.to_s.gsub(/(\\.|[^A-Za-z0-9.])+/, ".")+"X"
  end
  def JSlingCommon.resolveProxyJSTUNT uri
#    sIP=Socket.unpack_sockaddr_in(Socket.gethostbyname(dnsScrub(uri)+".jstunt.nutss.net")[3])[1]
    ["AF_INET",@@proxyPort,nil,JSlingCommon.host2ip(dnsScrub(uri))]
  end
  def JSlingCommon.host2ip(host)
    begin
      sHost=Socket.gethostbyname(host)[3]
      arr=[]
      sHost.split('').each do |c|
        arr.push(c.unpack("C"))  
      end
      sIP=arr.join(".")
    rescue
      sIP=nil
    end
    sIP
  end
  def JSlingCommon.resolveProxyDomain uri
    ["AF_INET",@@proxyPort,nil,JSlingCommon.host2ip(uri.split("@")[1])]
  end
  def JSlingCommon.resolveProxyFixed uri
    @@proxyFixedAddress
  end
  
end
class JSlingMessage
  class Type 
    JSLING_REGISTER="JSLING_REGISTER"
    JSLING_ROUTE="JSLING_ROUTE"
    JSLING_FORWARD="JSLING_FORWARD"
  end
  class Response 
    JSLING_ERROR="JSLING_ERROR"
    JSLING_SUCCESS="JSLING_SUCCESS"
  end
end
if $0==__FILE__ then
  #  Test.JSlingCommon
  JSlingCommon.init
  p JSlingCommon.resolveProxy("m2@202.38.64.1")
  JSlingCommon.init("FIXED")
  p JSlingCommon.resolveProxy("m2@202.38.64.1")
  JSlingCommon.init("FIXED","localhost")
  p JSlingCommon.resolveProxy("m2@202.38.64.1")
  JSlingCommon.init("FIXED","202.38.64.3")
  p JSlingCommon.resolveProxy("m2@202.38.64.1")
  JSlingCommon.init("JSTUNT","202.38.64.3",123)
  p JSlingCommon.resolveProxy("m2@202.38.64.1")
end